namespace XEAS.Framework.ShellLib
{
    using System;
    using System.Runtime.CompilerServices;
    using System.Runtime.InteropServices;
    using System.Text;

    public class ShellApi
    {
        public static short GetHResultCode(int hr)
        {
            hr &= 0xffff;
            return (short) hr;
        }

        [DllImport("user32.dll")]
        public static extern uint RegisterWindowMessage([MarshalAs(UnmanagedType.LPTStr)] string lpString);
        [DllImport("shell32.dll")]
        public static extern void SHAddToRecentDocs(uint uFlags, IntPtr pv);
        [DllImport("shell32.dll")]
        public static extern void SHAddToRecentDocs(uint uFlags, [MarshalAs(UnmanagedType.LPWStr)] string pv);
        [DllImport("shell32.dll")]
        public static extern uint SHAppBarMessage(uint dwMessage, ref APPBARDATA pData);
        [DllImport("shell32.dll")]
        public static extern int SHBindToParent(IntPtr pidl, [MarshalAs(UnmanagedType.LPStruct)] Guid riid, out IntPtr ppv, ref IntPtr ppidlLast);
        [DllImport("shell32.dll")]
        public static extern IntPtr SHBrowseForFolder(ref BROWSEINFO lbpi);
        [DllImport("shell32.dll")]
        public static extern void SHChangeNotify(uint wEventId, uint uFlags, IntPtr dwItem1, IntPtr dwItem2);
        [DllImport("shell32.dll")]
        public static extern IntPtr ShellExecute(IntPtr hwnd, [MarshalAs(UnmanagedType.LPStr)] string lpOperation, [MarshalAs(UnmanagedType.LPStr)] string lpFile, [MarshalAs(UnmanagedType.LPStr)] string lpParameters, [MarshalAs(UnmanagedType.LPStr)] string lpDirectory, int nShowCmd);
        [DllImport("shell32.dll")]
        public static extern int ShellExecuteEx(ref SHELLEXECUTEINFO lpExecInfo);
        [DllImport("shell32.dll", CharSet=CharSet.Unicode)]
        public static extern int SHFileOperation(ref SHFILEOPSTRUCT lpFileOp);
        [DllImport("shell32.dll")]
        public static extern int SHGetDesktopFolder(out IntPtr ppshf);
        [DllImport("shell32.dll")]
        public static extern int SHGetFolderLocation(IntPtr hwndOwner, int nFolder, IntPtr hToken, uint dwReserved, out IntPtr ppidl);
        [DllImport("shell32.dll")]
        public static extern int SHGetFolderPath(IntPtr hwndOwner, int nFolder, IntPtr hToken, uint dwFlags, StringBuilder pszPath);
        [DllImport("shell32.dll")]
        public static extern int SHGetMalloc(out IntPtr hObject);
        [DllImport("shell32.dll")]
        public static extern int SHGetPathFromIDList(IntPtr pidl, StringBuilder pszPath);
        [DllImport("shell32.dll")]
        public static extern int SHInvokePrinterCommand(IntPtr hwnd, uint uAction, [MarshalAs(UnmanagedType.LPWStr)] string lpBuf1, [MarshalAs(UnmanagedType.LPWStr)] string lpBuf2, int fModal);
        [DllImport("shell32.dll")]
        public static extern int SHParseDisplayName([MarshalAs(UnmanagedType.LPWStr)] string pszName, IntPtr pbc, out IntPtr ppidl, uint sfgaoIn, out uint psfgaoOut);
        [DllImport("shlwapi.dll")]
        public static extern int StrRetToBSTR(ref STRRET pstr, IntPtr pidl, [MarshalAs(UnmanagedType.BStr)] out string pbstr);
        [DllImport("shlwapi.dll")]
        public static extern int StrRetToBuf(ref STRRET pstr, IntPtr pidl, StringBuilder pszBuf, uint cchBuf);

        [StructLayout(LayoutKind.Sequential)]
        public struct APPBARDATA
        {
            public uint cbSize;
            public IntPtr hWnd;
            public uint uCallbackMessage;
            public uint uEdge;
            public ShellApi.RECT rc;
            public int lParam;
        }

        public delegate int BrowseCallbackProc(IntPtr hwnd, uint uMsg, int lParam, int lpData);

        [StructLayout(LayoutKind.Sequential)]
        public struct BROWSEINFO
        {
            public IntPtr hwndOwner;
            public IntPtr pidlRoot;
            [MarshalAs(UnmanagedType.LPStr)]
            public string pszDisplayName;
            [MarshalAs(UnmanagedType.LPStr)]
            public string lpszTitle;
            public uint ulFlags;
            [MarshalAs(UnmanagedType.FunctionPtr)]
            public ShellApi.BrowseCallbackProc lpfn;
            public int lParam;
            public int iImage;
        }

        public enum CSIDL
        {
            CSIDL_ADMINTOOLS = 0x30,
            CSIDL_ALTSTARTUP = 0x1d,
            CSIDL_APPDATA = 0x1a,
            CSIDL_BITBUCKET = 10,
            CSIDL_CDBURN_AREA = 0x3b,
            CSIDL_COMMON_ADMINTOOLS = 0x2f,
            CSIDL_COMMON_ALTSTARTUP = 30,
            CSIDL_COMMON_APPDATA = 0x23,
            CSIDL_COMMON_DESKTOPDIRECTORY = 0x19,
            CSIDL_COMMON_DOCUMENTS = 0x2e,
            CSIDL_COMMON_FAVORITES = 0x1f,
            CSIDL_COMMON_MUSIC = 0x35,
            CSIDL_COMMON_PICTURES = 0x36,
            CSIDL_COMMON_PROGRAMS = 0x17,
            CSIDL_COMMON_STARTMENU = 0x16,
            CSIDL_COMMON_STARTUP = 0x18,
            CSIDL_COMMON_TEMPLATES = 0x2d,
            CSIDL_COMMON_VIDEO = 0x37,
            CSIDL_CONTROLS = 3,
            CSIDL_COOKIES = 0x21,
            CSIDL_DESKTOP = 0,
            CSIDL_DESKTOPDIRECTORY = 0x10,
            CSIDL_DRIVES = 0x11,
            CSIDL_FAVORITES = 6,
            CSIDL_FLAG_CREATE = 0x8000,
            CSIDL_FONTS = 20,
            CSIDL_HISTORY = 0x22,
            CSIDL_INTERNET = 1,
            CSIDL_INTERNET_CACHE = 0x20,
            CSIDL_LOCAL_APPDATA = 0x1c,
            CSIDL_MYDOCUMENTS = 12,
            CSIDL_MYMUSIC = 13,
            CSIDL_MYPICTURES = 0x27,
            CSIDL_MYVIDEO = 14,
            CSIDL_NETHOOD = 0x13,
            CSIDL_NETWORK = 0x12,
            CSIDL_PERSONAL = 5,
            CSIDL_PRINTERS = 4,
            CSIDL_PRINTHOOD = 0x1b,
            CSIDL_PROFILE = 40,
            CSIDL_PROFILES = 0x3e,
            CSIDL_PROGRAM_FILES = 0x26,
            CSIDL_PROGRAM_FILES_COMMON = 0x2b,
            CSIDL_PROGRAMS = 2,
            CSIDL_RECENT = 8,
            CSIDL_SENDTO = 9,
            CSIDL_STARTMENU = 11,
            CSIDL_STARTUP = 7,
            CSIDL_SYSTEM = 0x25,
            CSIDL_TEMPLATES = 0x15,
            CSIDL_WINDOWS = 0x24
        }

        public enum PrinterActions
        {
            PRINTACTION_OPEN,
            PRINTACTION_PROPERTIES,
            PRINTACTION_NETINSTALL,
            PRINTACTION_NETINSTALLLINK,
            PRINTACTION_TESTPAGE,
            PRINTACTION_OPENNETPRN,
            PRINTACTION_DOCUMENTDEFAULTS,
            PRINTACTION_SERVERPROPERTIES
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct RECT
        {
            public int left;
            public int top;
            public int right;
            public int bottom;
        }

        public enum SFGAO : uint
        {
            SFGAO_BROWSABLE = 0x8000000,
            SFGAO_CANCOPY = 1,
            SFGAO_CANDELETE = 0x20,
            SFGAO_CANLINK = 4,
            SFGAO_CANMONIKER = 0x400000,
            SFGAO_CANMOVE = 2,
            SFGAO_CANRENAME = 0x10,
            SFGAO_CAPABILITYMASK = 0x177,
            SFGAO_COMPRESSED = 0x4000000,
            SFGAO_CONTENTSMASK = 0x80000000,
            SFGAO_DISPLAYATTRMASK = 0xfc000,
            SFGAO_DROPTARGET = 0x100,
            SFGAO_ENCRYPTED = 0x2000,
            SFGAO_FILESYSANCESTOR = 0x10000000,
            SFGAO_FILESYSTEM = 0x40000000,
            SFGAO_FOLDER = 0x20000000,
            SFGAO_GHOSTED = 0x8000,
            SFGAO_HASPROPSHEET = 0x40,
            SFGAO_HASSTORAGE = 0x400000,
            SFGAO_HASSUBFOLDER = 0x80000000,
            SFGAO_HIDDEN = 0x80000,
            SFGAO_ISSLOW = 0x4000,
            SFGAO_LINK = 0x10000,
            SFGAO_NEWCONTENT = 0x200000,
            SFGAO_NONENUMERATED = 0x100000,
            SFGAO_READONLY = 0x40000,
            SFGAO_REMOVABLE = 0x2000000,
            SFGAO_SHARE = 0x20000,
            SFGAO_STORAGE = 8,
            SFGAO_STORAGEANCESTOR = 0x800000,
            SFGAO_STORAGECAPMASK = 0x70c50008,
            SFGAO_STREAM = 0x400000,
            SFGAO_VALIDATE = 0x1000000
        }

        public enum SHCIDS : uint
        {
            SHCIDS_ALLFIELDS = 0x80000000,
            SHCIDS_BITMASK = 0xffff0000,
            SHCIDS_CANONICALONLY = 0x10000000,
            SHCIDS_COLUMNMASK = 0xffff
        }

        public enum SHCONTF
        {
            SHCONTF_FOLDERS = 0x20,
            SHCONTF_INCLUDEHIDDEN = 0x80,
            SHCONTF_INIT_ON_FIRST_NEXT = 0x100,
            SHCONTF_NETPRINTERSRCH = 0x200,
            SHCONTF_NONFOLDERS = 0x40,
            SHCONTF_SHAREABLE = 0x400,
            SHCONTF_STORAGE = 0x800
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct SHELLEXECUTEINFO
        {
            public uint cbSize;
            public uint fMask;
            public IntPtr hwnd;
            [MarshalAs(UnmanagedType.LPWStr)]
            public string lpVerb;
            [MarshalAs(UnmanagedType.LPWStr)]
            public string lpFile;
            [MarshalAs(UnmanagedType.LPWStr)]
            public string lpParameters;
            [MarshalAs(UnmanagedType.LPWStr)]
            public string lpDirectory;
            public int nShow;
            public IntPtr hInstApp;
            public IntPtr lpIDList;
            [MarshalAs(UnmanagedType.LPWStr)]
            public string lpClass;
            public IntPtr hkeyClass;
            public uint dwHotKey;
            public IntPtr hIconMonitor;
            public IntPtr hProcess;
        }

        [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
        public struct SHFILEOPSTRUCT
        {
            public IntPtr hwnd;
            public uint wFunc;
            public IntPtr pFrom;
            public IntPtr pTo;
            public ushort fFlags;
            public int fAnyOperationsAborted;
            public IntPtr hNameMappings;
            [MarshalAs(UnmanagedType.LPWStr)]
            public string lpszProgressTitle;
        }

        public enum SHGFP_TYPE
        {
            SHGFP_TYPE_CURRENT,
            SHGFP_TYPE_DEFAULT
        }

        public enum SHGNO
        {
            SHGDN_FORADDRESSBAR = 0x4000,
            SHGDN_FOREDITING = 0x1000,
            SHGDN_FORPARSING = 0x8000,
            SHGDN_INFOLDER = 1,
            SHGDN_NORMAL = 0
        }

        [StructLayout(LayoutKind.Explicit)]
        public struct STRRET
        {
            [FieldOffset(4)]
            public IntPtr cStr;
            [FieldOffset(4)]
            public IntPtr pOleStr;
            [FieldOffset(4)]
            public IntPtr pStr;
            [FieldOffset(4)]
            public uint uOffset;
            [FieldOffset(0)]
            public uint uType;
        }

        public enum STRRET_TYPE
        {
            STRRET_WSTR,
            STRRET_OFFSET,
            STRRET_CSTR
        }
    }
}

